// 在多线程中回调定时器函数，在 timer5 的基础上，缩小临界区，把不需要互斥执行的代码移出来。
#include <muduo/net/EventLoop.h>
#include <muduo/net/EventLoopThread.h>
#include <muduo/base/Mutex.h>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>

using namespace muduo;
using namespace muduo::net;
using namespace std;

class Printer : boost::noncopyable {
public:
	Printer(EventLoop *loop1, EventLoop *loop2)
		: loop1_(loop1), loop2_(loop2), count_(0) {
		loop1_->runAfter(1, boost::bind(&Printer::Print1, this));
		loop2_->runAfter(1, boost::bind(&Printer::Print2, this));
	}

	~Printer() {
		// cout << "final count is " << count_ << endl; not thread safe
		printf("final count is %d\n", count_);
	}

private:
	void Print1() {
		int count = 0;
		bool shouldQuit = false;
		{
			MutexLockGuard lock(mutex_);
			if (count_ < 10) {
				count = count_;
				++count_;
			} else {
				shouldQuit = true;
			}
		}
		
		if (shouldQuit) {
			loop1_->quit();
		} else {
			printf("timer1****** %d\n", count);
			loop1_->runAfter(1, boost::bind(&Printer::Print1, this));
		}
	}

	void Print2() {
		int count = 0;
		bool shouldQuit = false;
		{
			MutexLockGuard lock(mutex_);
			if (count_ < 10) {
				count = count_;
				++count_;
			} else {
				shouldQuit = true;
			}
		}
		
		if (shouldQuit) {
			loop2_->quit();
		} else {
			printf("timer2****** %d\n", count);
			loop2_->runAfter(1, boost::bind(&Printer::Print2, this));
		}
	}

	EventLoop *loop1_;
	EventLoop *loop2_;
	MutexLock mutex_;
	int count_;
};

int 
main() {
	boost::scoped_ptr<Printer> printer;
	EventLoop loop;
	EventLoopThread loopThread;
	EventLoop *loopInAnotherThread = loopThread.startLoop();
	printer.reset(new Printer(&loop, loopInAnotherThread));
	loop.loop();
	return 0;
}